from fastapi import APIRouter, Depends, Form, Request, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse, JSONResponse
from sqlalchemy.orm import Session
from ..models import get_db, WebsiteConfig, User, engine
from ..auth import get_current_user
import os
import time
from fastapi.templating import Jinja2Templates
from ..utils.db_tools import backup_database, get_latest_backup, get_all_backups, delete_backup, get_backup_dir

router = APIRouter()

# 获取模板目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
templates = Jinja2Templates(directory=os.path.join(BASE_DIR, "templates"))

# 网站配置页面
@router.get("/website-config", response_class=HTMLResponse)
async def admin_website_config(
    request: Request, 
    db: Session = Depends(get_db), 
    current_user: User = Depends(get_current_user)
):
    config = db.query(WebsiteConfig).first()
    if not config:
        config = WebsiteConfig(
            site_name="",
            site_description="",
            personal_intro="",
            icp_record="",
            copyright_info="",
            background_effect="gradient"
        )
    
    # 获取数据库文件路径
    db_path = engine.url.database
    
    # 获取所有备份文件信息
    all_backups = get_all_backups()
    
    # 获取当前背景图片URL
    current_background_image = None
    current_love_video = None
    try:
        # 尝试获取背景图片URL
        if hasattr(config, 'background_image_url'):
            current_background_image = config.background_image_url
        
    except Exception as e:
        print(f"获取媒体URL时出错: {str(e)}")
    
    return templates.TemplateResponse(
        "admin/website-config.html", 
        {
            "request": request, 
            "config": config, 
            "current_user": current_user,
            "db_path": db_path,
            "all_backups": all_backups,
            "current_background_image": current_background_image,
            "current_love_video": current_love_video
        }
    )

# 更新网站配置
@router.post("/website-config/update")
async def update_website_config(
    request: Request,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    # 手动获取表单数据
    form_data = await request.form()
    site_name = form_data.get("site_name", "")
    site_description = form_data.get("site_description", "")
    personal_intro = form_data.get("personal_intro", "")
    icp_record = form_data.get("icp_record", "")
    copyright_info = form_data.get("copyright_info", "")
    background_effect = form_data.get("background_effect", "stars")
    
    # 处理背景图片上传
    background_image_url = None
    if "background_image" in form_data and form_data["background_image"] != "":
        file = form_data["background_image"]
        # 检查文件类型
        if file.content_type.startswith("image/"):
            # 确保uploads目录存在
            upload_dir = os.path.join(BASE_DIR, "static", "uploads", "backgrounds")
            os.makedirs(upload_dir, exist_ok=True)
            
            # 生成唯一的文件名
            filename = f"background_{int(time.time())}_{file.filename}"
            filepath = os.path.join(upload_dir, filename)
            
            # 保存文件
            contents = await file.read()
            with open(filepath, "wb") as f:
                f.write(contents)
            
            # 生成相对URL
            background_image_url = f"/static/uploads/backgrounds/{filename}"
    
    # 移除爱情视频上传功能
    
    # 添加调试日志
    print(f"接收到的background_effect值: {background_effect}")
    
    # 允许的背景动效类型列表
    allowed_effects = ["none", "snow", "particles", "circles", "gradient", "starry-sky", "custom-image"]
    
    # 验证background_effect值
    if background_effect not in allowed_effects:
        print(f"无效的background_effect值: {background_effect}")
        # 如果是AJAX请求
        if request.headers.get("X-Requested-With") == "XMLHttpRequest":
            return JSONResponse(status_code=200, content={"status": "error", "message": "无效的背景动效类型"})
        else:
            return templates.TemplateResponse(
                "admin/website-config.html",
                {"request": request, "config": db.query(WebsiteConfig).first(), "current_user": current_user, "error": "无效的背景动效类型"}
            )
    
    config = db.query(WebsiteConfig).first()
    if config:
        config.site_name = site_name
        config.site_description = site_description
        config.personal_intro = personal_intro
        config.icp_record = icp_record
        config.copyright_info = copyright_info
        config.background_effect = background_effect
        # 如果上传了新图片，更新图片URL
        if background_image_url:
            config.background_image_url = background_image_url
        # 爱情视频功能已移除
    else:
        config = WebsiteConfig(
            site_name=site_name,
            site_description=site_description,
            personal_intro=personal_intro,
            icp_record=icp_record,
            copyright_info=copyright_info,
            background_effect=background_effect,
            background_image_url=background_image_url
        )
        db.add(config)
    
    try:
        db.commit()
        db.refresh(config)
        print(f"数据库提交成功，保存的background_effect值: {config.background_effect}")
    except Exception as e:
        db.rollback()
        print(f"数据库提交失败: {str(e)}")
        # 如果是AJAX请求
        if request.headers.get("X-Requested-With") == "XMLHttpRequest":
            return JSONResponse(status_code=200, content={"status": "error", "message": f"保存失败: {str(e)}"})
        else:
            return templates.TemplateResponse(
                "admin/website-config.html",
                {"request": request, "config": db.query(WebsiteConfig).first(), "current_user": current_user, "error": f"保存失败: {str(e)}"}
            )
    
    # 检查是否为AJAX请求
    is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
    if is_ajax:
        return JSONResponse(status_code=200, content={"status": "success", "message": "配置更新成功", "redirect": "/"})
    else:
        # 重定向到主页，这样新的背景动效配置才能生效
        return RedirectResponse(url="/", status_code=302)

# 备份数据库
@router.post("/backup-database")
async def backup_database_handler(
    request: Request,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    try:
        # 打印调试信息
        print("开始备份数据库...")
        
        # 获取数据库文件路径 - 优化路径处理逻辑
        db_path = engine.url.database
        print(f"从engine获取的数据库路径: {db_path}")
        
        # 确保使用绝对路径
        if not os.path.isabs(db_path):
            # 如果是相对路径，使用应用根目录构建绝对路径
            app_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
            db_path = os.path.join(app_root, db_path)
            print(f"转换为绝对路径: {db_path}")
        
        # 验证数据库文件是否存在
        if not os.path.exists(db_path):
            error_msg = f"数据库文件不存在: {db_path}"
            print(error_msg)
            is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
            if is_ajax:
                return {"status": "error", "message": error_msg}
            else:
                return templates.TemplateResponse(
                    "admin/website-config.html",
                    {"request": request, "config": db.query(WebsiteConfig).first() or WebsiteConfig(), 
                     "current_user": current_user, "error": error_msg}
                )
        
        # 验证数据库文件大小
        db_size = os.path.getsize(db_path)
        print(f"数据库文件大小: {db_size} 字节")
        
        # 执行备份
        print("执行备份函数...")
        success, message = backup_database(db_path)
        print(f"备份结果: 成功={success}, 消息={message}")
        
        if success:
            # 验证备份文件是否创建成功
            if os.path.exists(message):
                backup_size = os.path.getsize(message)
                print(f"备份文件创建成功: {message}, 大小: {backup_size} 字节")
                
                # 检查是否配置了自动发送邮件
                try:
                    from ..utils.email_tools import send_database_backup_email
                    from ..config import get_config
                    config = get_config()
                    if config.getboolean('backup', 'send_email', fallback=False):
                        print("发送备份邮件...")
                        send_database_backup_email(config, message)
                except Exception as email_error:
                    print(f"发送备份邮件失败: {str(email_error)}")
                
                is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
                if is_ajax:
                    return {"status": "success", "message": "数据库备份成功", "backup_path": message}
                else:
                    return RedirectResponse(request.url_for("admin_website_config"), status_code=303)
            else:
                error_msg = f"备份文件创建失败，文件不存在: {message}"
                print(error_msg)
                is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
                if is_ajax:
                    return {"status": "error", "message": error_msg}
                else:
                    return templates.TemplateResponse(
                        "admin/website-config.html",
                        {"request": request, "config": db.query(WebsiteConfig).first() or WebsiteConfig(), 
                         "current_user": current_user, "error": error_msg}
                    )
        else:
            # 检查是否为AJAX请求
            is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
            if is_ajax:
                return {"status": "error", "message": message}
            else:
                return templates.TemplateResponse(
                    "admin/website-config.html",
                    {"request": request, "config": db.query(WebsiteConfig).first() or WebsiteConfig(), 
                     "current_user": current_user, "error": message}
                )
    except Exception as e:
        error_msg = f"备份过程发生异常: {str(e)}"
        print(error_msg)
        import traceback
        traceback.print_exc()  # 打印完整的异常堆栈
        
        is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
        if is_ajax:
            return {"status": "error", "message": error_msg}
        else:
            return templates.TemplateResponse(
                "admin/website-config.html",
                {"request": request, "config": db.query(WebsiteConfig).first() or WebsiteConfig(), 
                 "current_user": current_user, "error": error_msg}
            )


# 获取自动备份配置
@router.get("/get-backup-config")
async def get_backup_config(
    request: Request,
    current_user: User = Depends(get_current_user)
):
    """获取自动备份配置"""
    try:
        from ..config import get_config
        config = get_config()
        
        # 从配置中读取备份设置
        backup_section = config.get('backup', {}) if isinstance(config, dict) else config.backup
        backup_enabled = backup_section.get('enabled', False) if isinstance(backup_section, dict) else getattr(backup_section, 'enabled', False)
        if isinstance(backup_enabled, str):
            backup_enabled = backup_enabled.lower() == 'true'
        frequency = backup_section.get('frequency', 'daily') if isinstance(backup_section, dict) else getattr(backup_section, 'frequency', 'daily')
        backup_time = backup_section.get('time', '00:00') if isinstance(backup_section, dict) else getattr(backup_section, 'time', '00:00')
        weekday = backup_section.get('weekday', '0') if isinstance(backup_section, dict) else getattr(backup_section, 'weekday', '0')
        send_email = backup_section.get('send_email', False) if isinstance(backup_section, dict) else getattr(backup_section, 'send_email', False)
        if isinstance(send_email, str):
            send_email = send_email.lower() == 'true'
        to_email = backup_section.get('to_email', '') if isinstance(backup_section, dict) else getattr(backup_section, 'to_email', '')
        
        return JSONResponse(content={
            "enabled": backup_enabled,
            "frequency": frequency,
            "time": backup_time,
            "weekday": weekday,
            "send_email": send_email,
            "to_email": to_email
        })
    except Exception as e:
        return JSONResponse(
            content={"success": False, "message": str(e)},
            status_code=500
        )


# 保存自动备份配置
@router.post("/save-backup-config")
async def save_backup_config(
    request: Request,
    current_user: User = Depends(get_current_user)
):
    """保存自动备份配置"""
    # 导入模块移到函数顶部，确保在异常处理时可用
    from ..config import get_config, CONFIG_DIR, DATABASE_URL
    from ..utils.scheduler import get_scheduler
    import configparser
    import logging
    
    try:
        logging.debug("开始保存备份配置")
        config_dict = get_config()  # get_config() 始终返回字典
        
        # 获取请求数据
        data = await request.json()
        logging.debug(f"接收到的配置数据: {data}")
        
        # 更新配置字典
        if 'backup' not in config_dict:
            config_dict['backup'] = {}
        
        # 直接使用字典操作，确保值为字符串类型
        # 特别处理布尔值，确保正确转换为'True'或'False'
        config_dict['backup']['enabled'] = 'True' if data.get('enabled', False) else 'False'
        config_dict['backup']['frequency'] = str(data.get('frequency', 'daily'))
        config_dict['backup']['time'] = str(data.get('time', '00:00'))
        config_dict['backup']['weekday'] = str(data.get('weekday', '0'))
        config_dict['backup']['send_email'] = 'True' if data.get('send_email', False) else 'False'
        config_dict['backup']['to_email'] = str(data.get('to_email', ''))
        
        # 写入配置文件
        config_path = os.path.join(CONFIG_DIR, 'config.ini')
        logging.debug(f"尝试写入配置文件: {config_path}")
        
        # 使用configparser写入配置
        config_writer = configparser.ConfigParser()
        for section, items in config_dict.items():
            if isinstance(items, dict):
                config_writer[section] = items
        
        with open(config_path, 'w', encoding='utf-8') as f:
            config_writer.write(f)
        logging.debug("配置文件写入成功")
        
        # 更新调度器配置 - 使用scheduler实例的实际方法
        try:
            scheduler = get_scheduler()
            # 从DATABASE_URL中提取数据库文件路径
            db_path = DATABASE_URL.replace('sqlite:///', '')
            # 使用load_config方法更新配置
            scheduler.load_config(config_dict, db_path)
            # scheduler._update_tasks()  # 可以直接调用私有方法更新任务，或者让调度器在下一个循环自动更新
            logging.debug("调度器配置更新成功")
        except Exception as scheduler_error:
            logging.error(f"调度器配置更新失败: {str(scheduler_error)}")
            # 调度器更新失败不影响配置保存
        
        return JSONResponse(content={"success": True, "message": "配置保存成功"})
    except Exception as e:
        logging.error(f"保存备份配置失败: {str(e)}", exc_info=True)
        return JSONResponse(
            content={"success": False, "message": f"保存失败: {str(e)}"},
            status_code=500
        )


# 测试备份邮件
@router.post("/test-backup-email")
async def test_backup_email(
    request: Request,
    current_user: User = Depends(get_current_user)
):
    """测试发送备份邮件"""
    # 导入模块移到函数顶部，确保在异常处理时可用
    from ..config import get_config
    from ..utils.email_tools import send_database_backup_email
    import datetime
    import logging
    import os
    import json
    
    try:
        logging.debug("开始测试备份邮件功能")
        config_dict = get_config()  # get_config() 始终返回字典
        
        # 获取请求数据，处理可能的JSON解析错误
        try:
            data = await request.json()
        except json.JSONDecodeError:
            data = {}
        to_email = data.get('to_email', '')
        
        # 如果提供了to_email参数，则临时覆盖配置中的to_email
        if to_email:
            if 'backup' not in config_dict:
                config_dict['backup'] = {}
            config_dict['backup']['to_email'] = to_email
            logging.debug(f"使用请求中的邮箱地址: {to_email}")
        
        # 检查是否配置了邮件设置
        email_section = config_dict.get('email', {})
        logging.debug(f"邮件配置部分: {email_section}")
        
        # 检查邮件配置是否完整
        if not email_section:
            return JSONResponse(
                content={"success": False, "message": "邮件配置不存在"},
                status_code=400
            )
        
        # 检查SMTP服务器是否配置
        if not email_section.get('smtp_server', ''):
            return JSONResponse(
                content={"success": False, "message": "邮件服务器未配置"},
                status_code=400
            )
        
        # 检查是否有收件人邮箱
        if 'backup' not in config_dict or 'to_email' not in config_dict['backup'] or not config_dict['backup']['to_email']:
            return JSONResponse(
                content={"success": False, "message": "请提供收件人邮箱地址"},
                status_code=400
            )
        
        # 创建一个测试备份文件用于发送
        test_backup_path = os.path.join(get_backup_dir(), f'test_backup_{datetime.datetime.now().strftime("%Y%m%d_%H%M%S")}.sql')
        logging.debug(f"创建测试备份文件: {test_backup_path}")
        
        # 确保目录存在
        os.makedirs(os.path.dirname(test_backup_path), exist_ok=True)
        
        # 创建测试内容
        with open(test_backup_path, 'w') as f:
            f.write('-- 这是一封测试邮件的备份文件示例\n')
            f.write(f'-- 测试时间: {datetime.datetime.now()}\n')
        
        # 尝试发送邮件
        logging.debug("准备发送测试邮件")
        success, message = send_database_backup_email(config_dict, test_backup_path)
        logging.debug(f"邮件发送结果: 成功={success}, 消息={message}")
        
        # 清理测试文件
        if os.path.exists(test_backup_path):
            os.remove(test_backup_path)
            logging.debug("测试备份文件已清理")
        
        if success:
            return JSONResponse(content={"success": True, "message": f"测试邮件发送成功: {message}"})
        else:
            return JSONResponse(
                content={"success": False, "message": f"测试邮件发送失败: {message}"},
                status_code=500
            )
    except Exception as e:
        logging.error(f"测试备份邮件失败: {str(e)}", exc_info=True)
        return JSONResponse(
            content={"success": False, "message": f"测试失败: {str(e)}"},
            status_code=500
        )


# 下载备份文件
@router.get("/download-backup/{backup_filename}")
async def download_backup(
    backup_filename: str,
    current_user: User = Depends(get_current_user)
):
    backup_dir = get_backup_dir()
    backup_path = os.path.join(backup_dir, backup_filename)
    
    if not os.path.exists(backup_path) or not backup_filename.startswith("guzian_backup_"):
        raise HTTPException(status_code=404, detail="备份文件不存在")
    
    def iterfile():
        with open(backup_path, "rb") as f:
            while chunk := f.read(8192):
                yield chunk
    
    return StreamingResponse(
        iterfile(),
        media_type="application/sql",
        headers={
            "Content-Disposition": f"attachment; filename={backup_filename}"
        }
    )

# 删除备份文件
@router.post("/delete-backup/{backup_filename}")
async def delete_backup_handler(
    backup_filename: str,
    request: Request,
    current_user: User = Depends(get_current_user)
):
    try:
        success = delete_backup(backup_filename)
        
        is_ajax = request.headers.get("X-Requested-With") == "XMLHttpRequest"
        
        if success:
            if is_ajax:
                return {"status": "success", "message": "备份文件删除成功"}
            else:
                return RedirectResponse(request.url_for("admin_website_config"), status_code=303)
        else:
            if is_ajax:
                return {"status": "error", "message": "备份文件删除失败或文件不存在"}
            else:
                raise HTTPException(status_code=404, detail="备份文件不存在")
    except Exception as e:
        if request.headers.get("X-Requested-With") == "XMLHttpRequest":
            return {"status": "error", "message": f"删除失败: {str(e)}"}
        else:
            raise HTTPException(status_code=500, detail="删除备份文件时发生错误")